package org.com.config;
import jakarta.websocket.*;
import jakarta.websocket.server.ServerEndpoint;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

//监听websocket地址/myWs
@ServerEndpoint("/myWs")
@Component
public class WebSocketServer {
    // 使用ConcurrentHashMap是因为这是一个并发程序
    private static final Map<String, Session> sessions = new ConcurrentHashMap<>();
    private static final AtomicInteger onlineCount = new AtomicInteger(0);

    @OnOpen
    public void onOpen(Session session) {
        // session表示WebSocket连接会话
        sessions.put(session.getId(), session);
        int count = onlineCount.incrementAndGet();
        broadcastSystemMessage("用户加入，当前在线人数：" + count);
        sendOnlineCount(count);
    }

    @OnMessage
    public void onMessage(String message, Session session) {
        broadcastUserMessage(session.getId(), message);
    }

    @OnClose
    public void onClose(Session session) {
        sessions.remove(session.getId());
        int count = onlineCount.decrementAndGet();
        broadcastSystemMessage("用户离开，当前在线人数：" + count);
        sendOnlineCount(count);
    }

    @OnError
    public void onError(Session session, Throwable error) {
        error.printStackTrace();
    }

    private void broadcastUserMessage(String senderId, String message) {
        //
        sessions.forEach((id, session) -> {
            if(!id.equals(senderId)) {
                try {
                    session.getBasicRemote().sendText(
                            "{\"type\":\"user\",\"content\":\"" + message + "\"}"
                    );
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    private void broadcastSystemMessage(String message) {
        sessions.forEach((id, session) -> {
            try {
                session.getBasicRemote().sendText(
                        "{\"type\":\"system\",\"content\":\"" + message + "\"}"
                );
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }

    private void sendOnlineCount(int count) {
        sessions.forEach((id, session) -> {
            try {
                session.getBasicRemote().sendText(
                        "{\"type\":\"count\",\"count\":" + count + "}"
                );
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }
}
